import axios, { AxiosError } from 'axios'
import { defaultRequestInterceptors, defaultResponseInterceptors } from './config'

import { AxiosInstance, InternalAxiosRequestConfig, RequestConfig, AxiosResponse } from './types'
import { ElMessage, ElLoading } from 'element-plus'
import { REQUEST_TIMEOUT } from '@/constants'
import { useUserStoreWithOut } from '@/store/modules/user'
export const PATH_URL = import.meta.env.VITE_API_BASE_PATH
import router from '@/router'
const abortControllerMap: Map<string, AbortController> = new Map()
const axiosInstance: AxiosInstance = axios.create({
  timeout: REQUEST_TIMEOUT,
  baseURL: PATH_URL
})

let loading = null

axiosInstance.interceptors.request.use((res: InternalAxiosRequestConfig) => {
  const controller = new AbortController()
  const url = res.url || ''
  res.signal = controller.signal
  const userStore = useUserStoreWithOut()
  abortControllerMap.set(
    import.meta.env.VITE_USE_MOCK === 'true' ? url.replace('/mock', '') : url,
    controller
  )
  const userinfo = userStore.getUserInfo
  if (userinfo) {
    res.headers.Authorization = 'Bearer ' + userinfo.access_token // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
  } else {
    res.headers.Authorization = 'Basic YXBwOmFwcA==' // 增加客户端认证
  }
  loading = ElLoading.service({
    lock: true,
    text: 'Loading',
    background: 'rgba(0, 0, 0, 0.7)'
  })
  return res
})

axiosInstance.interceptors.response.use(
  (res: AxiosResponse) => {
    if (res.status === 200)
      ElMessage({
        message: '成功!',
        type: 'success'
      })
    // 这里不能做任何处理，否则后面的 interceptors 拿不到完整的上下文了
    loading.close()
    return res
  },
  (error: AxiosError) => {
    console.log(router)
    // router.push({ name: 'Login' }).catch((err) => {
    //   if (err.name !== 'NavigationDuplicated') {
    //     throw err
    //   }
    // })
    // router.replace('/login')
    console.log('err： ' + error) // for debug
    ElMessage.error(error.message)
    loading.close()
    return Promise.reject(error)
  }
)

axiosInstance.interceptors.request.use(defaultRequestInterceptors)
// axiosInstance.interceptors.response.use(defaultResponseInterceptors)

const service = {
  request: (config: RequestConfig) => {
    return new Promise((resolve, reject) => {
      if (config.interceptors?.requestInterceptors) {
        config = config.interceptors.requestInterceptors(config as any)
      }

      axiosInstance
        .request(config)
        .then((res) => {
          resolve(res)
        })
        .catch((err: any) => {
          reject(err)
        })
    })
  },
  cancelRequest: (url: string | string[]) => {
    const urlList = Array.isArray(url) ? url : [url]
    for (const _url of urlList) {
      abortControllerMap.get(_url)?.abort()
      abortControllerMap.delete(_url)
    }
  },
  cancelAllRequest() {
    for (const [_, controller] of abortControllerMap) {
      controller.abort()
    }
    abortControllerMap.clear()
  }
}

export default service
